package com.jl.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jl.commons.constant.Constants;
import com.jl.commons.excel.DeviceExcel;
import com.jl.commons.result.DeviceRunStatus;
import com.jl.commons.result.PageDataInfo;
import com.jl.commons.shiro.ShiroUser;
import com.jl.commons.utils.CopyBean;
import com.jl.mapper.*;
import com.jl.model.*;
import com.jl.model.in.DeviceIn;
import com.jl.model.in.ProductionLineDevice;
import com.jl.service.IDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 设备表 服务实现类
 * </p>
 *
 * @author JiangJian
 * @since 2019-03-06
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {

    @Autowired
    private ComponentMapper componentMapper;

    @Autowired
    private DeviceComponentMapper deviceComponentMapper;

    @Autowired
    private FaultInfoMapper faultInfoMapper;
    @Autowired
    private DevicePartMapper devicePartMapper;

    @Override
    public void selectDeviceDataGrid(PageDataInfo<Map<String, Object>> pageDataInfo, QueryWrapper<Device> qw) {
        Page<Map<String, Object>> page = new Page<>();
        page.setSize(pageDataInfo.getSize());
        page.setCurrent(pageDataInfo.getCurrent());
        List<Map<String, Object>> mapList = baseMapper.selectDataGrid(page, qw);
        pageDataInfo.setTotal(page.getTotal());
        pageDataInfo.setRecords(mapList);
    }

    @Override
    public boolean deleteDeviceByIds(List<Long> ids) {
        //先删除device_component中的全部数据
        QueryWrapper<DeviceComponent> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("device_id", ids);
        deviceComponentMapper.delete(queryWrapper);
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public DeviceRunStatus getDeviceStatus(Long deviceId, Integer type, String time) {
        DeviceRunStatus deviceRunStatus = new DeviceRunStatus();
        /*
            1、获取某周(月)该设备的故障列表
            2、遍历所有的故障信息，判断故障时长是否大于两小时
            3、判断次数是否大于等于3
            4、查询本周是否拥有重复的故障部位
         */
        List<FaultInfo> overTwoHoursFaultInfo = new ArrayList<>();
        //查询某周(月)该设备的所有故障信息
        List<FaultInfo> faultInfoList = faultInfoMapper.selectWeekMonthFaultInfo(deviceId, type, time);
        //判断是否超过两小时
        for (FaultInfo faultInfo : faultInfoList) {
            if (faultInfo.getStopDuration() > Constants.TWO_HOUR) {
                overTwoHoursFaultInfo.add(faultInfo);
            }
        }
        //获取某周的重复故障部位信息
        List<DevicePart> repeatDamagePart = devicePartMapper.selectWeekMonthRepeatPart(deviceId, type, time);
        deviceRunStatus.setDeviceParts(repeatDamagePart);
        deviceRunStatus.setOverTowHourFaultInfo(overTwoHoursFaultInfo);
        //判断是周 还是 月
        if (Constants.DEVICE_RUN_STATUS_WEEK_TYPE.equals(type)) {
            deviceRunStatus.setType(Constants.DEVICE_RUN_STATUS_WEEK_TYPE);
            //判断是否故障超过三次
            if (faultInfoList.size() > Constants.DEVICE_WEEK_FAULT_REPEAT) {
                //超过两次则表示是在 严重不佳 和 不佳 中的其中一个
                if (repeatDamagePart.isEmpty() && overTwoHoursFaultInfo.isEmpty()) {
                    //如果没有 重复的故障部位 和 超过两个小时的故障信息则，表示是 返回 设备不佳状态
                    deviceRunStatus.setStatus(Constants.RUN_DOWN);
                } else {
                    //如果有 重复的故障部位 或者 超过两个小时的故障信息则 表示是 返回 设备严重不佳状态
                    deviceRunStatus.setStatus(Constants.SEVERE_CONDITION_NOT_GOOD);
                }
            } else {
                //不超过两次则表示是在 一般 和 良好 中的其中一个
                if (repeatDamagePart.isEmpty() && overTwoHoursFaultInfo.isEmpty()) {
                    //如果没有 重复的故障部位 和 超过两个小时的故障信息则，表示是 返回 设备良好状态
                    deviceRunStatus.setStatus(Constants.GOOD_CONDITION);
                } else {
                    //如果有 重复的故障部位 或者 超过两个小时的故障信息则 表示是 返回 设备一般状态
                    deviceRunStatus.setStatus(Constants.GENERAL_STATE);
                }
            }
        } else {
            //设备月运行状态
            deviceRunStatus.setType(Constants.DEVICE_RUN_STATUS_MONTH_TYPE);
            if (faultInfoList.size() > Constants.DEVICE_MONTH_FAULT_REPEAT) {
                deviceRunStatus.setStatus(Constants.SEVERE_CONDITION_NOT_GOOD);
            } else {
                deviceRunStatus.setStatus(Constants.GENERAL_STATE);
            }
        }
        return deviceRunStatus;
    }

    @Override
    public List<ProductionLineDevice> getLineDeviceRunInfo(Long lineId) {
        List<ProductionLineDevice> lineDeviceList = baseMapper.selectLineDeviceByProductionLine(lineId);
        return lineDeviceList;
    }

    @Override
    public boolean saveDeviceWithModel(ShiroUser currUser, Device device) {
        //新增数据
        device.setCreateId(currUser.getId());
        device.setGmtCreate(new Date());
        boolean saveDevice = baseMapper.insert(device) > 0;
        if (saveDevice) {
            Long modelId = device.getModelId();
            //新增加所有部位的配件到device_component的表格中
            List<DeviceComponent> deviceComponentList = new ArrayList<>();
            //获取当前所选择的设备类型的 所有配件信息
            List<Component> componentList = componentMapper.selectComponentByModelId(modelId);
            deviceComponentList.addAll(CopyBean.componentsToDeviceComponents(currUser.getId(), device, modelId, componentList));

            if (null != deviceComponentList && !deviceComponentList.isEmpty()) {
                return deviceComponentMapper.insertBatch(deviceComponentList) > 0;
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean updateDeviceWithModel(ShiroUser currUser, Device device) {
        device.setModifyId(currUser.getId());
        device.setGmtModified(new Date());
        boolean updateDevice = baseMapper.updateById(device) > 0;
        if (updateDevice) {
            //如果修改了部位信息
            if (device.isHasChangeModel()) {
                Long modelId = device.getModelId();
                /*
                    1、删除device_component中的配件信息
                    2、插入新的配件信息到device_component中
                 */
                //删除之前的device_component表中信息
                boolean deleteComponent = deviceComponentMapper.deleteDeviceComponentWithDeviceId(device.getId())>0;
                // 插入新的device_component数据
                List<DeviceComponent> deviceComponentList = new ArrayList<>();
                List<Component> componentList = componentMapper.selectComponentByModelId(modelId);
                deviceComponentList.addAll(CopyBean.componentsToDeviceComponents(currUser.getId(), device, modelId, componentList));
                boolean addComponent = deviceComponentMapper.insertBatch(deviceComponentList) >0;
                return deleteComponent && addComponent;
            } else {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<DeviceExcel> selectDeviceExcelByIds(List<Long> ids) {
        return baseMapper.selectDeviceExcelByIds(ids);
    }

    @Override
    public boolean isDeviceNumberUsed(String number) {
        return baseMapper.selectDeviceNumberCount(number) > 0;
    }

    @Override
    public boolean isDeviceNumberCanUse(String number, Long deviceId) {
        DeviceIn deviceIn = baseMapper.selectDeviceInByNumber(number);
        if (deviceIn == null) {
            //如果找不到数据则表示该数据没有被使用
            return true;
        } else {
            if (deviceIn.getId().equals(deviceId)) {
                //如果这个数据就是他本身则可以使用
                return true;
            }
        }
        return false;
    }

    @Override
    public DeviceIn selectDeviceInById(Long deviceId) {
        return baseMapper.selectDeviceInById(deviceId);
    }

    @Override
    public void getRepeatDamageDeviceInMonth(PageDataInfo<Map<String, Object>> pageDataInfo, String startTime, String endTime) {
        Page<Map<String, Object>> page = new Page<>();
        page.setSize(pageDataInfo.getSize());
        page.setCurrent(pageDataInfo.getCurrent());
        List<Map<String, Object>> mapList = baseMapper.selectRepeatDamageDeviceInMonth(page, startTime, endTime);
        pageDataInfo.setTotal(page.getTotal());
        pageDataInfo.setRecords(mapList);
    }

    /******************************************统计代码**************************************************/
    @Override
    public void getTopFaultTimeDevice(PageDataInfo<Map<String, Object>> pageDataInfo, Integer type, String startTime, String endTime) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (Constants.DEVICE_RUN_STATUS_WEEK_TYPE.equals(type)) {
//            周
            mapList = baseMapper.selectTopFaultTimeDevice(type, startTime, null);
        } else if (Constants.DEVICE_RUN_STATUS_MONTH_TYPE.equals(type)) {
//            月
            mapList = baseMapper.selectTopFaultTimeDevice(type, startTime, endTime);
        }
        pageDataInfo.setTotal(mapList.size());
        pageDataInfo.setRecords(mapList);
    }

    @Override
    public void getTopFaultCountDevice(PageDataInfo<Map<String, Object>> pageDataInfo, Integer type, String startTime, String endTime) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (Constants.DEVICE_RUN_STATUS_WEEK_TYPE.equals(type)) {
//            周
            mapList = baseMapper.selectTopFaultCountDevice(type, startTime, null);
        } else if (Constants.DEVICE_RUN_STATUS_MONTH_TYPE.equals(type)) {
//            月
            mapList = baseMapper.selectTopFaultCountDevice(type, startTime, endTime);
        }
        pageDataInfo.setTotal(mapList.size());
        pageDataInfo.setRecords(mapList);
    }

    @Override
    public void getTopOverHourCountDevice(PageDataInfo<Map<String, Object>> pageDataInfo, Integer type, String startTime, String endTime) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (Constants.DEVICE_RUN_STATUS_WEEK_TYPE.equals(type)) {
//            周
            mapList = baseMapper.selectTopOverHourCountDevice(type, startTime, null);
        } else if (Constants.DEVICE_RUN_STATUS_MONTH_TYPE.equals(type)) {
//            月
            mapList = baseMapper.selectTopOverHourCountDevice(type, startTime, endTime);
        }
        pageDataInfo.setTotal(mapList.size());
        pageDataInfo.setRecords(mapList);
    }
}
